package com.coollang.smartbra.bleutil.callback;

import com.coollang.smartbra.base.MyApplication;
import com.coollang.smartbra.beans.StepBean;
import com.coollang.smartbra.bleutil.BleUtil;
import com.coollang.smartbra.constant.Constants;
import com.coollang.smartbra.eventbus.CommonEvent;
import com.coollang.smartbra.utils.Command;
import com.coollang.smartbra.utils.DataUtils;
import com.coollang.smartbra.utils.MD5Utils;
import com.coollang.smartbra.utils.TimeUtils;
import com.google.gson.Gson;
import com.inuker.bluetooth.library.connect.listener.BluetoothStateListener;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.search.SearchResult;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;

import java.util.ArrayList;
import java.util.List;

import de.greenrobot.event.EventBus;
import okhttp3.Call;

/**
 * 接口回调统一管理类
 */

public abstract class BleCallbackImpl extends BluetoothStateListener implements BleCallback {

    private static final String TAG = BleCallbackImpl.class.getSimpleName();


    public void onSearchStarted() {

    }

    @Override
    public void onScan(SearchResult result) {

    }


    @Override
    public void onScanStop() {

    }

    public void onBleConnected() {

    }

    /**
     * 蓝牙断开连接
     */
    public void onBleDisconnected() {
    }

    /**
     * 蓝牙打开关闭状态的回调
     */
    @Override
    public void onBluetoothStateChanged(boolean openOrClosed) {
        // true表示蓝牙已打开，false表示蓝牙关闭
    }

    /**
     * 蓝牙连接
     */
    public void onResponse(int code, BleGattProfile data) {

    }

    /**
     * 写入状态
     */
    public void onResponse(int code) {

    }

    /**
     * 通知的回调
     */
    public void onNotify(byte[] data) {
        // 根据值分流

        if (data != null && DataUtils.sumCheckORD(data) && data[0] == Constants.BLE_Command_head) {
            if (data[1] == (byte) 0x21) {
                // 版本号
                String deviceVersion = (String) DataUtils.bytetoString(data).subSequence(2, 16);
                MyApplication.getApplication().version = deviceVersion.trim();
                onVersionRecieved(deviceVersion.trim());
            } else if (data[1] == (byte) 0x22 && DataUtils.sumCheckORD(data)) {
                // 电池电量的返回值
                onDevicePowerGet(DataUtils.getIntByByte(data[2]));
                MyApplication.getApplication().betery = DataUtils.getIntByByte(data[2]);
                EventBus.getDefault().post(new CommonEvent("", CommonEvent.REQUESTSUEECCD, CommonEvent.DISPALYALL));
            } else if (data[1] == (byte) 0x05) {
                // 固件升级
                onBleUpdate();
            } else if (data[1] == (byte) 0x04) {
                // 恢复出厂设置
            } else if (data[1] == (byte) 0x38) {
                // 同步九天数据
                saveStepData(data);
            }

            // ==================================== 运动相关 ================================================
            switch (data[1]) {
                case (byte) 0x23:
                    // 动作识别
                    if (data[2] == (byte) 0x01) {
                        onActionZhengFan(data[3], data[4]);
                    }
                    break;
                case (byte) 0x30:
                    // 同步步数   A9 30 00 C3 00 0E 00 08 00 00 00 00 00 00 00 00 00 00 00 B2
                    onStepsRecieved(data, DataUtils.getIntByByte(data[2]) * 256 + DataUtils.getIntByByte(data[3]), DataUtils.getIntByByte(data[4]) * 256 + DataUtils.getIntByByte(data[5]), DataUtils.getIntByByte(data[6]) * 256 + DataUtils.getIntByByte(data[7]));
                    // 上传同步步数
                    break;
                // 跑步
                case (byte) 0x31:
                    runningData(data);
                    break;
                                /*
                // 平板支撑
                case (byte) 0x32:
                    pbzcData(data);
                    break;
                 // 仰卧起坐
                 case (byte) 0x33:
                 ywqzData(data);
                 break;
                // 卷腹
                case (byte) 0x34:
                    jfData(data);
                    break;
                // 俯卧撑
                case (byte) 0x35:
                    fwcData(data);
                    break;
                // 深蹲跳
                case (byte) 0x36:
                    sdtData(data);
                    break;
                // 深蹲
                case (byte) 0x37:
                    sdData(data);
                    break;                */


                // ============ 新版九个动作 ==================================
                case Command.ACTION_32:
                case Command.ACTION_33:
                case Command.ACTION_34:
                case Command.ACTION_35:
                case Command.ACTION_36:
                case Command.ACTION_37:
                case Command.ACTION_25:
                case Command.ACTION_26:
                case Command.ACTION_27:
                case Command.ACTION_28:
                case Command.ACTION_29:
                case Command.ACTION_2A:
                case Command.ACTION_2B:
                case Command.ACTION_2C:
                case Command.ACTION_2D:
                    analysisCountData(data);
                    break;

                // ===========================================================

                // ==================================== 传感器检测 ================================================
                // 心率
                case (byte) 0x40:
                    heartRataData(data);
                    break;
                // 环境检测, 温湿度
                case (byte) 0x41:
                    if (data[2] == (byte) 0x01) {
                        onEnMeasureDataRecieved(DataUtils.getIntByByte(data[3]), (DataUtils.getIntByByte(data[4]) * 256 + DataUtils.getIntByByte(data[5])) / 10, DataUtils.getIntByByte(data[6]), DataUtils.getIntByByte(data[7]));
                    }
                    break;
                // 检测VOC
                case (byte) 0x43:
                    if (data[2] == (byte) 0x00) {
                        // 可以开始测量
                        onVOCMeasureStart(data[3]);
                    } else if (data[2] == (byte) 0x01) {
                        // 收到返回的数据了
                        int jiaquan = DataUtils.getIntByByte(data[8]) * 256 + DataUtils.getIntByByte(data[9]);
                        int tvoc = DataUtils.getIntByByte(data[10]) * 256 + DataUtils.getIntByByte(data[11]) / 1000;
                        int co2 = (DataUtils.getIntByByte(data[12]) * 65536 + DataUtils.getIntByByte(data[13]) * 256 + DataUtils.getIntByByte(data[14])) / 1000;

                        onVOCMeasureData(jiaquan, tvoc, co2);
                    }
                    break;
                default:
                    break;
            }

            // ==================================== 固件升级 ================================================
            switch (data[1]) {
                case (byte) 0x06:
                    onUpdateDataBackup(data[3], data[4], data[5], data[6], data[7], data[8]);
                    break;
                case (byte) 0x07:
                    onUpdateDataRecovery(data[3]);
                    break;
                case (byte) 0x08:
                    onUpdateDataRecoverySign(data[2]);
                    break;
                default:
                    break;
            }

        }
    }

    private void saveStepData(byte[] data) {
        if (data[2] == 1) {
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-1), data[3] * 256 + data[4]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-2), data[5] * 256 + data[6]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-3), data[7] * 256 + data[8]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-4), data[9] * 256 + data[10]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-5), data[11] * 256 + data[12]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-6), data[13] * 256 + data[14]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-7), data[15] * 256 + data[16]));
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-8), data[17] * 256 + data[18]));

            BleUtil.getInstance().sendData((byte) 0x38, (byte) 0x01);

        } else if (data[2] == 2) {
            // 第二次的数据同步
            mBeanList.add(new StepBean(TimeUtils.getFetureDateLong(-8), data[3] * 256 + data[4]));
            BleUtil.getInstance().sendData((byte) 0x38, (byte) 0x02);
            // 进行网络请求
            parserStepData();

        }
    }

    /**
     * 动作识别 检测设备正反是否错误
     */
    public void onActionZhengFan(byte zhengfan, byte qingxie) {
    }

    /**
     * 跑步
     */
    private void runningData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 跑步开始
        } else if (data[2] == (byte) 0x01) {
            // 跑步数据返回
            onRunDataRecieved(DataUtils.getIntByByte(data[3]) * 256 + DataUtils.getIntByByte(data[4]), DataUtils.getIntByByte(data[5]) * 256 + DataUtils.getIntByByte(data[6]), DataUtils.getIntByByte(data[7]));
        } else if (data[2] == (byte) 0x02) {
            // 暂停跑步
        } else if (data[2] == (byte) 0x03) {
            // 继续跑步
        } else if (data[2] == (byte) 0x04) {
            // 结束跑步
        }
    }

    private void pbzcData(byte[] data) {

        if (data[2] == (byte) 0x00) {
            // 开始平板支撑
        } else if (data[2] == (byte) 0x01) {
            // 平板支撑数据
            int heartRate = DataUtils.getIntByByte(data[5]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onPBZCRecieved(heartRate, errorFlag, errorType);


        } else if (data[2] == (byte) 0x02) {
            // 结束平板支撑
        }

    }


    private void ywqzData(byte[] data) {

        if (data[2] == (byte) 0x00) {
            // 开始仰卧起坐
        } else if (data[2] == (byte) 0x01) {
            // 仰卧起坐数据
            long upTime = DataUtils.getIntByByte(data[3]) * 25;
            long downTime = DataUtils.getIntByByte(data[4]) * 25;

            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onYWQZRecieved(upTime, downTime, heartRate, errorFlag, errorType);
        }
    }


    private void jfData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 开始卷腹
        } else if (data[2] == (byte) 0x01) {
            // 卷腹数据
            long upTime = DataUtils.getIntByByte(data[3]) * 25;
            long downTime = DataUtils.getIntByByte(data[4]) * 25;

            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onJFRecieved(upTime, downTime, heartRate, errorFlag, errorType);

        } else if (data[2] == (byte) 0x02) {
            // 结束卷腹
        }
    }

    protected void fwcData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 开始
        } else if (data[2] == (byte) 0x01) {
            // 俯卧撑数据
            long upTime = DataUtils.getIntByByte(data[3]) * 25;
            long downTime = DataUtils.getIntByByte(data[4]) * 25;

            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onFWCRecieved(upTime, downTime, heartRate, errorFlag, errorType);

        } else if (data[2] == (byte) 0x02) {
            // 结束俯卧撑
        }
    }


    // 深蹲跳
    protected void sdtData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 开始深蹲跳
        } else if (data[2] == (byte) 0x01) {
            // 深蹲跳数据

            long upTime = DataUtils.getIntByByte(data[3]) * 25;
            long downTime = DataUtils.getIntByByte(data[4]) * 25;

            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onSDTRecieved(upTime, downTime, heartRate, errorFlag, errorType);

        }
    }


    /**
     * 深蹲
     */
    protected void sdData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 开始深蹲
        } else if (data[2] == (byte) 0x01) {
            // 深蹲数据
            long upTime = DataUtils.getIntByByte(data[3]) * 25;
            long downTime = DataUtils.getIntByByte(data[4]) * 25;

            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            onSDRecieved(upTime, downTime, heartRate, errorFlag, errorType);


        } else if (data[2] == (byte) 0x02) {
            // 结束深蹲
        }
    }


    // 心率
    private void heartRataData(byte[] data) {
        if (data[2] == (byte) 0x00) {
            // 开始心率检测
        } else if (data[2] == (byte) 0x01) {
            // 心率数据
            onHeartRateRecieved(DataUtils.getIntByByte(data[3]), DataUtils.getIntByByte(data[4]), DataUtils.getIntByByte(data[5]));
        } else if (data[2] == (byte) 0x02) {
            // 结束心率检测
        }
    }

    // voc 测量开始
    public void onVOCMeasureStart(byte b) {
    }


    // ============================ 数据分流start ==========================================
    // 版本号
    protected void onVersionRecieved(String version) {
    }

    // 电池电量
    protected void onDevicePowerGet(int power) {
    }

    // 固件升级
    protected void onBleUpdate() {

    }

    // 同步步数
    protected void onStepsRecieved(byte[] data, int dates, long sportTimes, int steps) {
    }

    // 跑步数据返回
    protected void onRunDataRecieved(long runTimes, long runSteps, int currentHeartRate) {

    }

    protected void onPBZCRecieved(int heartRate, int errorFlag, int errorType) {

    }

    // 仰卧起坐数据
    protected void onYWQZRecieved(long upTime, long downTime, int heartRate, int errorFlag, int errorType) {
    }

    // 卷腹数据
    protected void onJFRecieved(long upTime, long downTime, int heartRate, int errorFlag, int errorType) {
    }


    // 俯卧撑数据
    protected void onFWCRecieved(long upTime, long downTime, int heartRate, int errorFlag, int errorType) {

    }


    // 深蹲跳 错误类型
    protected void onSDTRecieved(long upTime, long downTime, int heartRate, int errorFlag, int errorType) {
    }

    // 深蹲
    protected void onSDRecieved(long upTime, long downTime, int heartRate, int errorFlag, int errorType) {
    }

    //心率

    /**
     * @param alarm            0 不启动报警 1`启动报警
     * @param alarmHeartRate   报警心率
     * @param currentHeartRate 当前心率
     */
    protected void onHeartRateRecieved(int alarm, int alarmHeartRate, int currentHeartRate) {
    }


    //环境测量


    /**
     * @param tempState 温度的正 负      0 正数  1负数
     * @param temp      温度值
     * @param shidu     湿度
     * @param ziwaixian 紫外线
     */
    protected void onEnMeasureDataRecieved(int tempState, int temp, int shidu, int ziwaixian) {
    }

    /**
     * @param jiaquan 甲醛
     * @param tvoc    tvoc
     * @param co2     co2
     */
    public void onVOCMeasureData(int jiaquan, int tvoc, int co2) {

    }

    /**
     * 固件升级
     */
    public void onUpdateDataBackup(byte voc1, byte voc2, byte voc3, byte voc4, byte step1, byte step2) {

    }

    /**
     * 判断是否是新设备,如果是新设备,则向设备发送数据
     */
    protected void onUpdateDataRecovery(byte sign) {
    }


    /**
     * 数据恢复检验
     */
    protected void onUpdateDataRecoverySign(byte sign) {

    }

    private List<StepBean> mBeanList = new ArrayList<>();

    /**
     * 进行网络请求上传步数
     */
    private void parserStepData() {
        // 获取前一天数据
        String s = new Gson().toJson(mBeanList);
        requestUploadStep("action/add-step-action", "{\"data\": " + s + "}");
    }

    private void requestUploadStep(String url, String data) {
        String timeStamp = TimeUtils.getCurrentTimeUnixString();
        String sign = MD5Utils.getMD5(url.split("/")[1] + timeStamp);
        OkGo.get(Constants.HOST + url)
                .params("timestamp", timeStamp)
                .params("sign", sign)
                .params("username", MyApplication.mLogInDataBean.getUsername())
                .params("data", data)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, okhttp3.Response response) {
                    }
                });

    }
    // ============================ end ==========================================

    private static final int START_POSITION = 2;

    /**
     * 解析计数数据
     */
    private void analysisCountData(byte[] data) {
        if (data[START_POSITION] == Command.ACTION_01) {
            // 深蹲数据
            int heartRate = DataUtils.getIntByByte(data[6]);

            // 错误标志
            int errorFlag = DataUtils.getIntByByte(data[7]);
            int errorType = DataUtils.getIntByByte(data[8]);

            realCountData(heartRate, errorFlag, errorType);
        }
    }

    /**
     * @param heartRate 心率
     * @param errorFlag 1 正确
     *                  2 错误
     * @param errorType 错误的类型
     */
    protected void realCountData(int heartRate, int errorFlag, int errorType) {

    }
}
